#ifndef XICT_DRIVER_UTILS_UTILS_COMMON_H
#define XICT_DRIVER_UTILS_UTILS_COMMON_H

#include "string"
#include <chrono>

#define RESET "\033[0m"
#define BLACK "\033[30m"   /* Black */
#define RED "\033[31m"     /* Red */
#define GREEN "\033[32m"   /* Green */
#define YELLOW "\033[33m"  /* Yellow */
#define BLUE "\033[34m"    /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define CYAN "\033[36m"    /* Cyan */
#define WHITE "\033[37m"   /* White */

#define SYSTEM_TIME 0
#define STEADY_TIME 1

#define TIMESTAMP_TYPE SYSTEM_TIME

namespace xict_driver {
    namespace utils {
        /**
         * @brief 传感器类型
         *
         */
        enum SensorType {
            VAGUE = 0,   // 无效
            IMU,         // IMU
            GNSS,        // GNSS
            LIDAR,       // 激光雷达
            CAMERA,      // 相机
            CAN,         // CAN
        };

        /**
         * @brief 驱动类型
         *
         */
        enum DriverType {
            TYPE_VAGUE = 0x00,   // 无效驱动

            TYPE_WIT_IMU      = 0x11,   // 维特智能 IMU驱动
            TYPE_HIPNUC_IMU   = 0x12,   // 超核电子I MU驱动
            TYPE_ICM20602_IMU = 0x13,   // ICM-20602 IMU驱动
            TYPE_BMI055_IMU   = 0x14,   // BMI-055 IMU驱动
            TYPE_MG201_IMU    = 0x15,   // MG201 IMU驱动

            TYPE_STANDARD_GNSS = 0x21,   // 标定GNSS驱动(GPGGA+GPGST)
            TYPE_DLYD1A_GNSS = 0x22,   // 光纤GNSS驱动（型号：Dlyd1a）

            TYPE_DJI_CAMERA = 0x31,   // DJI相机驱动
            TYPE_GST_CAMERA = 0x32,   // GST相机驱动

            TYPE_LIDAR_MID360 = 0x41,   // mid360驱动

            TYPE_CAN_0 = 0x51,   // CAN0驱动
            TYPE_CAN_1 = 0x52,   // CAN1驱动

        };

        /**
         * @brief 串口奇偶校验
         *
         */
        enum SerialParity {
            NO_PARITY = 0,   // 无校验
            EVEN_PARITY,     // 偶校验
            ODD_PARITY       // 奇校验
        };

        /**
         * @brief 驱动状态
         *
         */
        enum DriverState {
            DS_IDLE = 0,   // 空闲状态
            DS_NORMAL,     // 正常状态
            DS_TIMEOUT,    // 超时状态
            DS_ERROR       // 错误状态
        };

        /**
         * @brief DJI相机类型
         *
         */
        enum DjiCameraType {
            DJI_FPV_CAMERA  = 0,   // DJI FPV相机
            DJI_MAIN_CAMERA = 1,   // DJI 主相机(H20N)
            DJI_VICE_CAMERA = 2,   // DJI 副相机(
            DJI_TOP_CAMERA  = 3    // DJI 顶相机
        };

        /**
         * @brief 驱动类型转传感器类型
         *
         * @param _driver_type
         * @return SensorType
         */
        inline SensorType DriverType2SensorType(const DriverType _driver_type) {
            if (_driver_type < 0x10) {
                return SensorType::VAGUE;
            } else if (_driver_type < 0x20) {
                return SensorType::IMU;
            } else if (_driver_type < 0x30) {
                return SensorType::GNSS;
            } else if (_driver_type < 0x40) {
                return SensorType::CAMERA;
            } else if (_driver_type < 0x50) {
                return SensorType::LIDAR;
            } else if (_driver_type < 0x60) {
                return SensorType::CAN;
            } else {
                return SensorType::VAGUE;
            }
        }

        /**
         * @brief 字符串转化为驱动类型
         *
         * @param _type
         * @return DriverType
         */
        inline DriverType StrToDriverType(const std::string& _type) {
            if (_type == "WIT_IMU") {
                return DriverType::TYPE_WIT_IMU;
            } else if (_type == "HIPNUC_IMU") {
                return DriverType::TYPE_HIPNUC_IMU;
            } else if (_type == "ICM20602_IMU") {
                return DriverType::TYPE_ICM20602_IMU;
            } else if (_type == "BMI055_IMU") {
                return DriverType::TYPE_BMI055_IMU;
            } else if (_type == "MG201_IMU") {
                return DriverType::TYPE_MG201_IMU;
            } else if (_type == "STANDARD_GNSS") {
                return DriverType::TYPE_STANDARD_GNSS;
            } else if (_type == "DJI_CAMERA") {
                return DriverType::TYPE_DJI_CAMERA;
            } else if (_type == "DLYD1A_GNSS") {
                return DriverType::TYPE_DLYD1A_GNSS;
            } else if (_type == "CAN0") {
                return DriverType::TYPE_CAN_0;
            } else if (_type == "CAN1") {
                return DriverType::TYPE_CAN_1;
            } else if (_type == "GST_CAMERA") {
                return DriverType::TYPE_GST_CAMERA;
            }

            return DriverType::TYPE_VAGUE;
        }

        /**
         * @brief 驱动类型转字符串
         *
         * @param _type
         * @return std::string
         */
        inline std::string DriverTypeToStr(const DriverType _type) {
            std::string str;
            switch (_type) {
            case DriverType::TYPE_WIT_IMU:
                str = "Wit-IMU-Driver";
                break;
            case DriverType::TYPE_HIPNUC_IMU:
                str = "HIPNUC-IMU-Driver";
                break;
            case DriverType::TYPE_MG201_IMU:
                str = "MG201_IMU";
                break;
            case DriverType::TYPE_STANDARD_GNSS:
                str = "Standard-GNSS-Driver";
                break;
            case DriverType::TYPE_DJI_CAMERA:
                str = "DJI-Camera-Driver";
                break;
            case DriverType::TYPE_DLYD1A_GNSS:
                str = "Dlyd1a-GNSS-Driver";
                break;
            case DriverType::TYPE_CAN_0:
                str = "CAN0";
                break;
            case DriverType::TYPE_CAN_1:
                str = "CAN1";
                break;
            case DriverType::TYPE_GST_CAMERA:
                str = "GST_CAMERA";
                break;
            default:
                str = "ERROR";
                break;
            }

            return str;
        }

        /**
         * @brief  获取系统时间
         *
         * @return double
         */
        inline double GetSystemTimeSecond() {
            std::chrono::time_point<std::chrono::system_clock,
                                    std::chrono::milliseconds>
                current_time =
                    std::chrono::time_point_cast<std::chrono::milliseconds>(
                        std::chrono::system_clock::now());
            return (double)current_time.time_since_epoch().count() * 1e-3;
        }

        /**
         * @brief Get the Steady Time Second object 获取稳定时间
         *
         * @return double
         */
        inline double GetSteadyTimeSecond() {
            std::chrono::time_point<std::chrono::steady_clock,
                                    std::chrono::milliseconds>
                current_time =
                    std::chrono::time_point_cast<std::chrono::milliseconds>(
                        std::chrono::steady_clock::now());
            return (double)current_time.time_since_epoch().count() * 1e-3;
        }
    }   // namespace utils
}   // namespace xict_driver

#endif